昨天說了很多次 Parser,但是那到底是是什麼呢?
其實 Parser 的其中一類就是將文字做解析的並將其轉換成 抽象語法樹(Abstract Syntax Tree,AST)的黑盒子函式。
打個比方,有個套件叫做 dotenv
他可以自動將 .env
檔案中的環境變數載入到 process.env
中。
使用如下 :
當我們有個 .env
檔案
# .env
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
我們就會取到下述的資訊
require('dotenv').config();
console.log(process.env);
// { S3_BUCKET: 'YOURS3BUCKET', SECRET_KEY: 'YOURSECRETKEYGOESHERE' }
其實 require('dotenv').config()
內部執行了 3 個動作
拆開來大概如下的感覺 ,
const dotenv = require('dotenv');
const fs = require('fs');
// 1. 讀取 .env 檔案
const properties = fs.readFileSync('.env').toString();
// 2. 將 .env 檔案內容轉換成 AST ( Parser )
const parsed = dotenv.parse(properties);
// 3. 將 AST 資訊放入 process.env 中
Object.keys(parsed).forEach(key => process.env[key] = parsed[key]);
// 4. 檢查 process.env 是否有 .env 的資料
console.log('process.env=', process.env);
第二步 , 就是所謂的 Parser ,
也就是說 , 文字經過 Parser 後 , 會變成一個 Object ( 我們可稱之為 AST )
明天我們就來更進一步的了解 dotenv 是如何將 .env
內的文字轉換成 AST 的。
感謝 lagagain 的補充 <(_ _)>,
Parser 函式的輸出結果不一定是 AST 也可以是 CST 或是 Byte Code
本文用詞不精準,應該說有一類的 Parser 會輸入文字 - 輸出 AST
Dotenv有parse的功能
但是拿Dotenv parse 後的結果當成是 AST 不是很妥當
維基上面對於AST的解說與應用有提到
It often serves as an intermediate representation of the program through several stages that the compiler requires
Dotenv parse後的object基本上就直接餵給 process.env
了,並沒有什麼再有什麼特殊的處理了
感謝 carternolan 的留言分享
筆者目前所知,只要是 Parsed Tree 都可以算是 AST 的一種
AST 也確實常跟 compiler 一起使用,不過 AST 不一定只能跟 compiler 使用吧
筆者目前所知,只要是 Parsed Tree 都可以算是 AST 的一種
想請問有這個資料的資料來源嗎
從中文 wiki看到的資料是
和抽象語法樹相對的是具體語法樹(通常稱作分析樹)
就與作者提到的有所衝突了
不曉得作者對於 AST 的定義為何?
抽象語法樹相對應的是具體語法樹(Concrete Syntax Tree, CST),也叫做解析樹(Parse Tree,或者Parsing Tree)。
-- 自己動手實現Lua
得說我比較認同 carternolan 所說的...
將文字解析成電腦或程式容易處理的格式或物件的過程,稱之為Parsing這沒什麼問題,其結果不一定都是叫做AST,有可能AST只是其中一個過程而已。
何況...下面結果實在感覺不出有樹(Tree)的樣子
{
"S3_BUCKET": "YOURS3BUCKET",
"SECRET_KEY": "YOURSECRETKEYGOESHERE"
}
以原始來源
# .env
S3_BUCKET="YOURS3BUCKET"
SECRET_KEY="YOURSECRETKEYGOESHERE"
CST可能被處理成
+ `<root>`
|-- "# .env" (token type: comment)
|
|-+ `<key pair>`
| |-- "S3_BUCKET" (token type: key)
| |--"="
| |--"YOURS3BUCKET" (token type: value)
|
|-+ `<key pair>`
| |-- "SECRET_KEY" (token type: key)
| |-- "="
| |-- "YOURSECRETKEYGOESHERE" (token type: value)
節點(node)可能帶有一些屬性,是後續處理上可能會使用到的。像是上例comment和"="的節點在處理上作用不大,可以被忽略,才變成抽象語法樹(AST)
+ `<root>`
|-+ `<key pair>`
| |-- "S3_BUCKET" (token type: key)
| |--"YOURS3BUCKET" (token type: value)
|
|-+ `<key pair>`
| |-- "SECRET_KEY" (token type: key)
| |-- "YOURSECRETKEYGOESHERE" (token type: value)
目前想要統一 30 天文章 Parse 結果有一個固定的名稱
所以可能結果要叫 ST ( Syntax Tree ) 比較妥當嗎 ?
非本科 , 研究 Parse 有些名稱比較不精準 , 可能要請多多包涵
整理一下邦友 carternolan lagagain 提到的幾個點,我分享一下個人觀點
(string)--tokenizer-->(tokens)--parser-->(AST)--render--> (HTML DOM)
所以 AST 應該不用必定跟 compiler 一同出現
Tree
Tree
的定義 , 他是其中一種沒錯 , 雖然單層感覺不像 Tree
Tree represents the nodes connected by edges
所以 AST 應該不用必定跟 compiler 一同出現
貼那段的意思重點在於 AST 是 intermediate representation
算是一個中間階段,當然並沒有一定要compiler一起使用
個人觀點的話是覺得作者寫出來的東西能夠對於讀者負責,希望用詞能夠更精準,而不是自己覺得很好就拿來使用,也不是用了一句非本科,請多包涵來帶過
Tree 大大加油
作者寫出來的東西能夠對於讀者負責,希望用詞能夠更精準,而不是自己覺得很好就拿來使用,也不是用了一句非本科,請多包涵來帶過
這點我非常同意,不過非本科真的需要 邦友
幫忙科普,因為網路上關於 AST 的文章有些有誤,而作者又沒有能力鑑別錯誤 (:з」∠)
感謝 carternolan 的指教